package com.xaicode.learn.netty.dubborpc.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;

/**
 * @author Locker xaicode@sina.com
 * @version 1.0
 * @date 2021/6/20 0020 21:49
 */
@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context;

    // server result
    private String result;

    // client params
    private String clientParam;

    // The Channel of the ChannelHandlerContext is now active
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // set context
        context = ctx;
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // set result
        result = msg.toString();
        log.info("receive server reply: {}", result);

        // Wakes up a single thread that is waiting on this object's monitor.
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    // Computes a result, or throws an exception if unable to do so.
    // Called by proxy class, send client params and wait for notifying (by channelRead) to return result.
    @Override
    public synchronized Object call() throws Exception {

        // send client params
        context.writeAndFlush(clientParam);
        // wait for notifying
        wait();

        return result;
    }

    public void setClientParam(String clientParam) {
        this.clientParam = clientParam;
    }
}
